//加载Scratch项目
import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';

//import storage from './storage';
import {activateTab,BLOCKS_TAB_INDEX} from '../reducers/editor-tab';
import {
    LoadingStates,
    getIsFetchingWithId,
    getIsLoadingWithId,
    getIsShowingProject,
    setProjectData,
    projectError,
    setProjectUnchanged
} from '../reducers/project-state';

const {requestProject} = require('../session-api.js');//向服务器请求作品的源代码
/* 高阶组件：根据ID加载作品。If there's no id, the default project is loaded？？？
 * @param {React.Component} WrappedComponent component to receive projectData prop
 * @returns {React.Component} component with project loading behavior
 */
const ProjectFetcherHOC = function (WrappedComponent) {
    class ProjectFetcherComponent extends React.Component {
        constructor (props) {
            super(props);

            //storage.setTranslatorFunction(props.intl.formatMessage);//BLJ：不知其用途
        }
        componentDidUpdate (prevProps) {
            // 当前isFetchingWithId=true && 前一个状态isFetchingWithId=false，防止重复加载
            if (this.props.isFetchingWithId && !prevProps.isFetchingWithId) {
                //console.log("BLJ:开始加载作品数据:"+this.props.projectId);
                new Promise((resolve, reject) => requestProject(resolve, reject, this.props.projectId))
                .then(body => {//服务器以JSON返回项目数据时的接口：
                    if (body.status=='ok'){
                        this.props.onSetProjectData(body.src);
                    } else {
                        this.props.onError('');
                        alert(body.status);
                        //新建一个作品
                        //改变hash，在hash-parser-hoc.jsx中有监听此事件，即可新建作品
                        window.location.hash='B';//随意写一个字符，使hash产生变化，才能触发监听事件
                        //去除url中hash的空#字符
                        history.pushState('B', 'B',window.location.pathname + window.location.search);
                    }
                })
                .catch(err => {
                    this.props.onError(err);
                });
            }

            //加载作品，并准备显示作品时
            if (this.props.isShowingProject) {
                //切换到积木Tab页面，方便可以直接编程
                if (prevProps.isLoadingProject) { this.props.onActivateTab(BLOCKS_TAB_INDEX); }
            }
        }

        render () {return (<WrappedComponent/>)}
    }
    ProjectFetcherComponent.propTypes = {
        isFetchingWithId: PropTypes.bool,
        isLoadingProject: PropTypes.bool,
        isShowingProject: PropTypes.bool,

        loadingState: PropTypes.oneOf(LoadingStates),
        onSetProjectData: PropTypes.func,
        onActivateTab: PropTypes.func,
        onProjectUnchanged: PropTypes.func,
        onError: PropTypes.func,

        //intl: intlShape.isRequired,
        projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    };

    const mapStateToProps = state => ({
        isFetchingWithId: getIsFetchingWithId(state.project.loadingState),
        isLoadingProject: getIsLoadingWithId(state.project.loadingState),
        isShowingProject: getIsShowingProject(state.project.loadingState),

        loadingState: state.project.loadingState,
        projectId: state.project.projectId
    });
    const mapDispatchToProps = dispatch => ({
        onSetProjectData: (projectData) => dispatch(setProjectData(projectData)),
        onError: error => dispatch(projectError(error)),
        onActivateTab: tab => dispatch(activateTab(tab)),
        onProjectUnchanged: () => dispatch(setProjectUnchanged())
    });
    // Allow incoming props to override redux-provided props. Used to mock in tests.
    const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(
        {}, stateProps, dispatchProps, ownProps
    );
    return connect(
        mapStateToProps,
        mapDispatchToProps,
        mergeProps
    )(ProjectFetcherComponent);
    // return injectIntl(connect(
    //     mapStateToProps,
    //     mapDispatchToProps,
    //     mergeProps
    // )(ProjectFetcherComponent));
};

export {
    ProjectFetcherHOC as default
};
